/*
 * psit.h - arquivo de definição da interface da biblioteca de threads
 */

#ifndef _PSIT_H_
#define _PSTI_H_

#include "psit_types.h"  /* Define os tipos thread_t e sem_t  */

/* A função que define o código de cada thread deve receber um inteiro
 * como único parâmetro e não deve retornar nenhum valor.
 */
typedef void (*thread_func)(int);

/* psit_init deve ser chamada pelo programa principal antes que qualquer
 * thread seja criada. Isso tem o efeito de criar a primeira thread, que
 * representa o programa principal, e instalar o tratador de sinais que
 * será acionado ao final de cada quantum para fazer a troca de
 * contextos.
 */
void psit_init(void);

/* Cada thread criada recebe um identificador único, com numeração
 * sequencial a partir de zero. Para uma thread se identificar ela deve
 * chamar a função psit_this_thread, que retorna o identificador da
 * thread corrente.
 */
int psit_this_thread(void);

/* Apesar do pacote de threads implementar preempção, pode ainda existir
 * o caso onde uma thread queira explicitamente abrir mão da CPU. Isso
 * é feito chamando a função psit_yield, que passará a execução para a
 * próxima thread pronta.
 */
void psit_yield(void);

/* psit_thread_create cria a thread que executará a função tf, que será
 * iniciada com o parâmetro arg. A thread é colocada imediatamente na
 * fila de threads prontas.
 */
thread_t* psit_thread_create(thread_func tf, int arg);

/* psit_wait_threads pode ser usado pelo programa principal para esperar
 * pela execução das threads. Como qualquer programa, o retorno da função
 * main termina o processo. Sendo assim, para simplificar o código, o
 * programa principal pode criar as threads e chamar essa função para
 * ficar suspenso até que elas terminem.
 */
void psit_wait_threads(void);

/* O mecanismo de exclusão mútua do pacote psit é o semáforo. O
 * funcionamento é o mesmo descrito no livro, controlado pelo seu valor
 * interno. Chamadas ao wait esperam se o valor for menor ou igual a zero.
 * Para fins de justiça, a ordem de acesso ao semáforo deve ser garantida.
 * Na criação pode-se definir o valor inicial do semáforo.
 */
sem_t* psit_sem_create(int valor);

void psit_sem_wait(sem_t *m);

void psit_sem_signal(sem_t *m);

#endif /* _PSTI_H_ */
